package com.atguigu.gmall.order.controller;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Api(tags = "service-order模块控制器")
@RestController
@RequestMapping("api/order")
public class OrderApiController {

    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private CartFeignClient cartFeignClient;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private RabbitService rabbitService;

    @ApiOperation(value = "获取订单信息列表")
    @GetMapping("auth/trade")
    public Result trade(HttpServletRequest request){
        Map<String, Object> result = new HashMap<>();
        String userId = AuthContextHolder.getUserId(request);
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.parseLong(userId));
        List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(userId);

        List<OrderDetail> detailArrayList = new ArrayList<>();
        for (CartInfo cartInfo : cartCheckedList) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuName(cartInfo.getSkuName());
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            orderDetail.setOrderPrice(cartInfo.getSkuPrice());
            detailArrayList.add(orderDetail);
        }
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderDetailList(detailArrayList);
        if (!CollectionUtils.isEmpty(detailArrayList)){
            orderInfo.sumTotalAmount();
        }
        //获取订单流水号，tradeNo，
        String tradeNo = orderService.getTradeNo(userId);
        result.put("tradeNo",tradeNo);

        result.put("userAddressList",userAddressList);
        result.put("detailArrayList", detailArrayList);
        result.put("totalNum",detailArrayList.size());
        result.put("totalAmount", orderInfo.getTotalAmount());
        return Result.ok(result);
    }

    @ApiOperation(value = "提交订单")
    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,HttpServletRequest request){
        String tradeNo = request.getParameter("tradeNo");
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));
        //校验订单流水号
        boolean flag = orderService.checkTradeNo(tradeNo, userId);
        if (!flag){
            return Result.fail().message("勿重复提交（不可无刷新回退提交）");
        }
        //删除流水号
        orderService.deleteTradeNo(userId);
        //验证库存与价格
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        List<CompletableFuture> completableFutureList = new ArrayList<>();
        List<String> errorList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            //验证库存
            CompletableFuture<Void> stockCompletableFuture = CompletableFuture.runAsync(() -> {
                boolean checkStock = orderService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
                if (!checkStock) {
                    errorList.add(orderDetail.getSkuName()+"库存不足");
                }
            });
            //异步任务对象，放入list
            completableFutureList.add(stockCompletableFuture);
            //验证价格
            CompletableFuture<Void> priceCompletableFuture = CompletableFuture.runAsync(() -> {
                BigDecimal lastPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
                BigDecimal orderPrice = orderDetail.getOrderPrice();
                if (orderPrice.compareTo(lastPrice) != 0) {
                    errorList.add(orderDetail.getSkuName() + "价格有变动，请核对后再提交订单");
                    //更改购物车中最新价格(下面)
                }
            });
            completableFutureList.add(priceCompletableFuture);
        }
        CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()])).join();
        if (errorList.size()>0){
            String errorMsg = StringUtils.join(errorList, ",");
            //更改购物车中最新价格
            if (errorMsg.indexOf("价格有变动") != -1){
                cartFeignClient.loadCartCache(userId);
            }
            return Result.fail().message(errorMsg);
        }
        //保存订单
        Long orderId = orderService.saveOrderInfo(orderInfo);
        //发送订单延时关闭任务（RabbitMq）
        rabbitService.sendDelayMessage(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,MqConst.ROUTING_ORDER_CANCEL,
                orderId,MqConst.DELAY_TIME);

        return Result.ok(orderId);
    }

    @ApiOperation(value = "根据订单id 获取订单信息")
    @GetMapping("inner/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable("orderId") Long orderId){
        OrderInfo orderInfo = orderService.getOrderInfoById(orderId);
        return orderInfo;
    }


    //库存系统传来的请求参数，?orderId=***&wareSkuMap=[{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
    //返回的字符串，为List<Map> 里面的Map 为拆完单之后的orderInfo 封装需要的字段信息的Map 返回给库存系统
    @ApiOperation("库存调用的拆单接口")
    @PostMapping("orderSplit")
    public String orderSplit(HttpServletRequest request){
        String orderId = request.getParameter("orderId");
        String wareSkuMap = request.getParameter("wareSkuMap");
        //根据orderId 和 wareSkuMap 信息进行拆单
        List<OrderInfo> orderInfoList = orderService.orderSplit(orderId,wareSkuMap);
        //声明一个List<Map> 进行接收下面封装的【对应每一个子单的】map
        List<Map> maps = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfoList) {
            Map map = orderService.initWareOrder(orderInfo);
            maps.add(map);
        }

        return JSON.toJSONString(maps);
    }

}
